#include "rtda/heap/class_member.h"
#include "classfile/class_file.hpp"
#include "rtda/heap/class.h"

namespace jvm {
namespace heap {

void ClassMember::copyMemberInfo(const std::shared_ptr<classfile::MemberInfo> pMemberInfo) {
    m_accessFlags = pMemberInfo->getAccessFlags();
    m_name = pMemberInfo->getName();
    m_descriptor = pMemberInfo->getDescriptor();
}

bool ClassMember::isPublic() const { return 0 != (m_accessFlags & ACC_PUBLIC); }
bool ClassMember::isPrivate() const { return 0 != (m_accessFlags & ACC_PRIVATE); }
bool ClassMember::isProtected() const { return 0 != (m_accessFlags & ACC_PROTECTED); }
bool ClassMember::isStatic() const { return 0 != (m_accessFlags & ACC_STATIC); }
bool ClassMember::isFinal() const { return 0 != (m_accessFlags & ACC_FINAL); }
bool ClassMember::isSynthetic() const { return 0 != (m_accessFlags & ACC_SYNTHETIC); }

const std::string& ClassMember::getName() const { return m_name; }
const std::string& ClassMember::getDescriptor() const { return m_descriptor; }
std::shared_ptr<Class> ClassMember::getClass() const { return m_pClass; }

bool ClassMember::isAccessibleTo(std::shared_ptr<Class> pD) const {
    if (isPublic()) {
        return true;
    }
    
    std::shared_ptr<Class> pC = m_pClass;
    if (isProtected()) {
        return pD == pC || pD->isSubClassOf(pC) || 
               pC->getPackageName() == pD->getPackageName();
    }
    
    if (!isPrivate()) {
        return pC->getPackageName() == pD->getPackageName();
    }
    
    return pD == pC;
}

} // namespace heap
} // namespace jvm